package com.itstherules.jmsunit.mock.store;

import com.itstherules.jmsunit.expectation.JmsExpectation;
import com.itstherules.jmsunit.headers.JmsHeadersDefinition;
import com.itstherules.jmsunit.mock.QueueRead;
import com.itstherules.jmsunit.mock.SendingInformation;

public class Store {

	private static final String LINE_SEPARATOR = System.getProperty("line.separator");

	private String throughDefinition;
	private String toQueue;
	private String replyMessage;
	private JmsHeadersDefinition toDefinition;
	private String correlationId;
	private CompositeExpectation expectations = new CompositeExpectation();
	private String queueNameToCheckAsEmpty;
	private QueueRead queueRead = QueueRead.SEQUENTIALLY;

	public final Store through(String throughDefinition) {
		this.throughDefinition = throughDefinition;
		return this;
	}

	public final Store through(String queue, QueueRead queueRead) {
		Store through = through(queue);
		through.queueRead = queueRead;
		return through;
	}

	public final Store with(JmsExpectation condition) {
		this.expectations.add(condition);
		return this;
	}

	public final Store reply(String queue, String message, JmsHeadersDefinition definition) {
		this.toQueue = queue;
		this.replyMessage = message;
		this.toDefinition = definition;
		return this;
	}
	
	public final String getThrough() {
		return throughDefinition;
	}
	
	public final QueueRead getQueueRead() {
		return queueRead;
	}
	
	public final SendingInformation getSendReplyInformation() {
		if(!requiresAReply()){
			throw new AssertionError("getSendReplyInformation() called when not all info filled in. The reply queue is " + nullGuard(toQueue) + ", the reply message is "+nullGuard(replyMessage)+", and the header definition for this reply is " + nullGuard(toDefinition).toString()+".  None of these values can be null");
		}
		return new SendingInformation(toQueue, replyMessage, toDefinition);
	}
	
	
	public final String getCorrelationId() {
		return correlationId;
	}

	public final void setCorrelationId(String correlationId) {
		this.correlationId = correlationId;
	}

	private Object nullGuard(Object value) {
		if(value==null){return "null"; }
		return value;
	}

	public final boolean requiresAReply() {
		if (toQueue == null || replyMessage == null || toDefinition == null) {
			return false;
		} return true;
	}

	@Override
	public String toString() {
		StringBuffer buffer = new StringBuffer();
		buffer.append("Expectation: ");
		buffer.append(LINE_SEPARATOR);
		if (throughDefinition != null) {
			buffer.append("through: ");
			buffer.append(throughDefinition);
			buffer.append(LINE_SEPARATOR);
		}
		buffer.append("with: ");
		buffer.append(expectations.toString());
		buffer.append(LINE_SEPARATOR);
		if (toQueue != null && replyMessage != null) {
			buffer.append("reply:");
			buffer.append(LINE_SEPARATOR);
			buffer.append("	with: ");
			buffer.append(replyMessage);
			buffer.append(LINE_SEPARATOR);
			buffer.append("	to: queue ");
			buffer.append(toQueue);
			buffer.append(LINE_SEPARATOR);
			buffer.append("	pretending to be: ");
			buffer.append(toDefinition.getName());
			buffer.append(" (");
			buffer.append(toDefinition.toString());
			buffer.append(")");
			buffer.append(LINE_SEPARATOR);
		}
		return buffer.toString();
	}

	public final CompositeExpectation getWithExpectations() {
		return expectations;
	}

	public final void queueIsEmpty(String queueName) {
		this.queueNameToCheckAsEmpty = queueName;
	}

	public final boolean queueIsEmptyStored() {
		return this.queueNameToCheckAsEmpty!=null;
	}

	public final String getQueueToCheckAsEmpty() {
		return queueNameToCheckAsEmpty;
	}

}
